﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using AncientLand.Common;
using Castle.Core;

namespace AncientLand.Controllers
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private static object _synRoot = new Object();
        private static WindsorControllerFactory _instance;

        public static WindsorControllerFactory Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_synRoot)
                    {
                        if (_instance == null)
                        {
                            _instance = new WindsorControllerFactory();
                        }
                    }

                }
                return _instance;
            }
        }


        // The constructor:
        // 1. Sets up a new IoC container
        // 2. Registers all components specified in web.config
        // 3. Registers all controller types as components
        private WindsorControllerFactory()
        {
            // Instantiate a container, taking configuration from web.config
            // container = new WindsorContainer(new XmlInterpreter()); //new ConfigResource("castle")
            // Also register all the controller types as transient

            //var controllerTypes =
            //    from t in Assembly.LoadFile(@"E:\FidGrades\Morningstar.Com.SiteDev.FidGrades\Morningstar.Com.SiteDev.FidGrades.Web\bin\Morningstar.Com.SiteDev.FidGrades.Controllers.dll").GetTypes()
            //    where typeof(IController).IsAssignableFrom(t)
            //    select t;

            //IOCContainer.Instance.Kernel.ReleasePolicy = new NoTrackingReleasePolicy(); 

            var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                                  where typeof(IController).IsAssignableFrom(t)
                                  select t;
            //controllerTypes = controllerTypes.Union(controllerTypes1);

            foreach (Type t in controllerTypes)
                IocContainer.Instance.AddComponentWithLifestyle(t.FullName, t, LifestyleType.Transient);
        }

        // Constructs the controller instance needed to service each request this part is Updated to be compatible with MVC 2
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                return base.GetControllerInstance(requestContext, controllerType);

            return (IController)IocContainer.Instance.Resolve(controllerType);
        }

        public override void ReleaseController(System.Web.Mvc.IController controller)
        {
            var disposable = controller as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }

            IocContainer.Instance.ReleaseComponent(controller);
            GC.Collect();
        }



    }
}
